import { Storage } from '@/utils/Storage';
import { request } from '@/utils/request';
import { AUTH_TOKEN_KEY } from '@/enums/cacheEnum';
import { RequestEnum } from '@/enums/httpEnum';

interface IProps {
  apiKey: string;
  type?: 'GET' | 'POST';
  initParam?: any;
  initConstantParams?: any;
  initPage?: { current?: number; size?: number };
  isCount?: boolean;
  isLoginRequired?: boolean;
  isMount?: boolean;
  showLoading?: boolean;
}

const useRequestList = ({
  apiKey,
  type = RequestEnum.GET,
  initParam,
  initConstantParams,
  initPage,
  isCount = true,
  isLoginRequired = false,
  isMount = true,
  showLoading = true,
}: IProps) => {
  const list = ref([]);
  const params = ref({
    ...initParam,
  });
  const constantParams = ref({
    ...initConstantParams,
  });
  const page = ref({
    current: 1,
    size: 20,
    total: 0,
    ...initPage,
  });
  const loading = ref(false);
  const hasMore = ref(false);

  const refreshingRef = ref(false);

  const setListData = (data: any) => {
    list.value = data;
  };

  const setParams = (paramValue: any) => {
    params.value = filterEmptyValues(paramValue);
  };

  const setPage = (pageValue: Object) => {
    const filteredPageValue = filterEmptyValues(pageValue);
    page.value = { size: page.value.size, ...filteredPageValue };
  };

  const filterEmptyValues = (obj: Object): any => {
    return Object.keys(obj).reduce((filteredObj, key) => {
      // 过滤null, undefined, ''等空值
      if (obj[key] !== null && obj[key] !== undefined && obj[key] !== '') {
        filteredObj[key] = obj[key];
      }
      return filteredObj;
    }, {});
  };

  const getList = async () => {
    loading.value = true;

    const sendParams = { ...constantParams.value, ...page.value, ...params.value };
    const paramsData = type === RequestEnum.GET ? { params: sendParams } : { data: sendParams };
    const res = await request({ url: apiKey, method: type, ...paramsData });

    loading.value = false;
    refreshingRef.value = false;
    if (res?.data) {
      setListData(
        isCount
          ? res.data.current > 1
            ? [...list.value, ...res.data.records]
            : (res.data.records as any[])
          : (res.data as any[]),
      );
      page.value.total = res.data.total;
      page.value.current = res.data.current;
      page.value.size = sendParams.size;
      hasMore.value = res.data.current * res.data.size < res.data.total;
      return;
    }

    hasMore.value = false;
  };

  onMounted(async () => {
    const token = Storage.get(AUTH_TOKEN_KEY);
    if (isLoginRequired && !token) {
      return;
    }

    if (!isMount) return;

    await getList();
  });

  watch(params, () => {
    list.value = [];
    page.value.current = 1;
    getList().then();
  });

  watch(page, () => {
    list.value = [];
    getList().then();
  });

  return {
    list,
    setListData,
    params,
    setParams,
    page,
    setPage,
    loading,
    hasMore,
    refreshingRef,
    getList,
  };
};

export default useRequestList;
